package jp.sourceforge.akjrcp.ffmpeg;

import java.util.ArrayList;
import java.util.List;

public class FFMpegCommandUtil {
/**
 * 
 * @param ffmpeg
 * @param overwrite
 * @param inputOptions 
 * maybe -r rate and -s size is needed
 * @param others
 * @return
 */
public static String[] makeInputPipeCommand(String ffmpeg,boolean overwrite,String[] inputOptions,String[] others){
	List<String> list=new ArrayList<String>();

	list.add(ffmpeg);
	if(overwrite){
		list.add("-y");
	}
	list.add("-f");
	list.add("image2pipe");
	
	list.add("-vcodec");
	list.add("mjpeg");
	
	for (int i = 0; i < inputOptions.length; i++) {
		list.add(inputOptions[i]);
	}
	
	list.add("-i");
	list.add("-");
	
	//if output file flv should it.
	//list.add("-vcodec");
	//list.add("flv");
	
	for (int i = 0; i < others.length; i++) {
		list.add((String)others[i]);
	}
	
	return (String[])list.toArray(new String[0]);
}
public static String[] makeInputPipeCommand(String ffmpeg,boolean overwrite){
	return makeInputPipeCommand(ffmpeg,overwrite,new String[0],new String[0]);
}

public static String[] makePCMOutputPipeCommand(String ffmpeg,String input,int rate,int channel){
	List<String> list=new ArrayList<String>();
	list.add(ffmpeg);
	list.add("-i");
	list.add(input);
	
	list.add("-f");
	list.add("s16le");//16bit signned int
	
	list.add("-ar");
	list.add(""+rate);
	
	list.add("-ac");
	list.add(""+channel);
	
	
	
	list.add("-"); //pipe
	
	
	return (String[])list.toArray(new String[0]);
}
public static final String[] MJPEG_HIGHQUALITY_EXPORT={"-vcodec","mjpeg","-qscale","1","-qmin","1","-qmax","1"};
public static final String[] MJPEG_HIGHQUALITY_EXPORT_NOAUDIO={"-vcodec","mjpeg","-qscale","1","-qmin","1","-qmax","1","-an"};
public static String[] makeJpegOutputPipeCommand(String ffmpeg,String input,String options[]){
	List<String> list=new ArrayList<String>();
	list.add(ffmpeg);
	list.add("-i");
	list.add(input);
	
	list.add("-f");
	list.add("image2pipe");
	
	list.add("-vcodec");
	list.add("mjpeg");
	
	list.add("-qscale");
	list.add("1");
	list.add("-qmin");
	list.add("1");
	list.add("-qmax");
	list.add("1");
	list.add("-an");
	
	for (int i = 0; i < options.length; i++) {
		list.add(options[i]);
	}
	
	//list.add("");
	list.add("-");
	
	
	return (String[])list.toArray(new String[0]);
}
/*
 * output must be like out%2d.jpg
 */
public static String[] makeJpegOutputFileCommand(String ffmpeg,String input,String output,String options[]){
	List<String> list=new ArrayList<String>();
	list.add(ffmpeg);
	list.add("-i");
	list.add(input);
	
	list.add("-f");
	list.add("image2");
	
	list.add("-vcodec");
	list.add("mjpeg");
	
	list.add("-qscale");
	list.add("1");
	list.add("-qmin");
	list.add("1");
	list.add("-qmax");
	list.add("1");
	list.add("-an");
	
	if(options!=null){
	for (int i = 0; i < options.length; i++) {
		list.add(options[i]);
	}
	}
	
	//list.add("");
	list.add(output);
	
	
	return (String[])list.toArray(new String[0]);
}

public static String[] makeJpegOutputPipeCommand(String ffmpeg,String input){
return makeJpegOutputPipeCommand(ffmpeg,input,new String[0]);
}

public static String[] makeWaveOutputPipeCommand(String ffmpeg,String input){
	List<String> list=new ArrayList<String>();
	list.add(ffmpeg);
	list.add("-i");
	list.add(input);
	
	list.add("-f");
	list.add("wav");
	
	//list.add("-acodec");
	//list.add("pcm_u16be");
	
	//list.add("");
	list.add("-");
	
	
	return (String[])list.toArray(new String[0]);
}
/*
 * for wav sample rate change
 */
public static String[] makeWaveSampleRateChangeCommand(String ffmpeg,String input,String output,int sampleRate){
	List<String> list=new ArrayList<String>();
	list.add(ffmpeg);
	list.add("-i");
	list.add(input);

	list.add("-ar");
	list.add(""+sampleRate);
	
	list.add(output);
	
	
	return (String[])list.toArray(new String[0]);
}

public static String[] copyAudioCommand(String ffmpeg,String input,String output){
	List<String> list=new ArrayList<String>();
	list.add(ffmpeg);
	list.add("-i");
	list.add(input);
	
	list.add("-vn");
	list.add("-acodec");
	list.add("copy");
	
	list.add(output);
	
	
	return (String[])list.toArray(new String[0]);
}

public static String[] copyInputsCommand(String ffmpeg,String inputs[],String format,String output){
	List<String> list=new ArrayList<String>();
	list.add(ffmpeg);
	for (int i = 0; i < inputs.length; i++) {
		list.add("-i");
		list.add(inputs[i]);
	}
	
	
	list.add("-vcodec");
	list.add("copy");
	list.add("-acodec");
	list.add("copy");
	
	list.add("-f");
	list.add(format);
	list.add(output);
	
	
	return (String[])list.toArray(new String[0]);
}

public static String toDigits(int value,int digit){
	String result=""+value;
	while(result.length()<digit){
		result="0"+result;
	}
	return result;
}

public static String[] makeJpegInputCommand(String ffmpeg,String inputDir,String head,int digit,String foot,String fps,String audioInput,String output){
return makeJpegInputCommand(ffmpeg,inputDir,head,digit,foot,fps,audioInput,"copy",new String[]{},output);

}
//TODO support overwrite
public static String[] makePCMInputCommand(String ffmpeg,String audioInput,String audioCodec,String options[],String output){
	List<String> list=new ArrayList<String>();
	list.add(ffmpeg);
	list.add("-y");//overwrite
	if(audioInput==null){
		return null;
	}
		list.add("-f"); //now raw pcm TODO change
		list.add("s16le");
		
		list.add("-ar");
		list.add("48000");
		
		list.add("-ac");
		list.add("2");
		
		list.add("-i");
		list.add(audioInput);
		
		list.add("-acodec");
		list.add(audioCodec);
		
		if(options!=null){
			for (int i = 0; i < options.length; i++) {
				list.add(options[i]);
			}
			}
		
		list.add(output);
		return (String[])list.toArray(new String[list.size()]);
}

public static String[] makePCMToWaveCommand(String ffmpeg,String audioInput,PCMData inputData,String options[],String output,String acodec,int frameRate,int channel){
	List<String> list=new ArrayList<String>();
	list.add(ffmpeg);
	list.add("-y");//overwrite
	if(audioInput==null){
		return null;
	}
		list.add("-f");
		list.add(inputData.getFormat());
		
		list.add("-ar");
		list.add(""+inputData.getFrameRate());
		
		list.add("-ac");
		list.add(""+inputData.getChannel());
		
		list.add("-i");
		list.add(audioInput);
		
		list.add("-acodec");
		if(acodec==null){
		list.add("pcm_s16le");//
		}else{
		list.add(acodec);
		}
		
		list.add("-ar");
		list.add(""+frameRate);//
		
		
		list.add("-ac");
		list.add(""+channel);//
		
		if(options!=null){
		for (int i = 0; i < options.length; i++) {
			list.add(options[i]);
		}
		}
		
		list.add(output);
		return (String[])list.toArray(new String[list.size()]);
}

public static class PCMData{
	private int frameRate;
	private int channel;
	private String format;
	public PCMData(String format,int frameRate,int channel){
		this.format=format;
		this.frameRate=frameRate;
		this.channel=channel;
	}
	public int getFrameRate() {
		return frameRate;
	}
	public void setFrameRate(int frameRate) {
		this.frameRate = frameRate;
	}
	public int getChannel() {
		return channel;
	}
	public void setChannel(int channel) {
		this.channel = channel;
	}
	public String getFormat() {
		return format;
	}
	public void setFormat(String format) {
		this.format = format;
	}
}

public static String[] makeJpegInputCommand(String ffmpeg,String inputDir,String head,int digit,String foot,String fps,String audioInput,String videoCodec,String audioCodec,String options[],String output){
	List<String> list=new ArrayList<String>();
	list.add(ffmpeg);
	list.add("-y");//overwrite
	//audio first is better
	if(audioInput!=null){
		list.add("-f"); //now raw pcm TODO change
		list.add("s16le");
		
		list.add("-ar");
		list.add("48000");
		
		list.add("-ac");
		list.add("2");
		
		list.add("-i");
		list.add(audioInput);
		}
	
	//set fps
	list.add("-r");
	list.add(fps);
	
	list.add("-i");
	String input=inputDir+"\\"+head+"%0"+digit+"d"+foot;
	
	list.add(input);
	
	if(audioInput!=null){
		list.add("-acodec");
		list.add(audioCodec);
	}else{
		//very important otherwise never write data.
		list.add("-an");
	}
	
	list.add("-vcodec");
	list.add(videoCodec);
	
	if(options!=null){
		for (int i = 0; i < options.length; i++) {
			list.add(options[i]);
		}
		}
	
	
	
	
	list.add(output);
	
	
	return (String[])list.toArray(new String[0]);
}

public static String[] makeMuxPCMAndVideoCommand(String ffmpeg,String input,String audioInput,String videoCodec,String audioCodec,String options[],String output){
	List<String> list=new ArrayList<String>();
	list.add(ffmpeg);
	list.add("-y");//overwrite
	//audio first is better
	if(audioInput!=null){
		list.add("-f"); //now raw pcm TODO change
		list.add("s16le");
		
		list.add("-ar");
		list.add("48000");
		
		list.add("-ac");
		list.add("2");
		
		list.add("-i");
		list.add(audioInput);
		}
	
	
	list.add("-i");
	list.add(input);
	
	
	if(audioInput!=null){
		list.add("-acodec");
		list.add(audioCodec);
	}else{
		//very important otherwise never write data.
		list.add("-an");
	}
	
	list.add("-vcodec");
	list.add(videoCodec);
	
	if(options!=null){
		for (int i = 0; i < options.length; i++) {
			list.add(options[i]);
		}
		}
	
	
	
	
	list.add(output);
	
	
	return (String[])list.toArray(new String[0]);
}

/**
 * 
 * @param ffmpeg
 * @param inputDir
 * @param head
 * @param digit
 * @param foot
 * @param fps
 * @param audioInput
 * @param videoCodec
 * @param options
 * @param output
 * 
 * @return
 * 
 * @deprecated
 */
public static String[] makeJpegInputCommand(String ffmpeg,String inputDir,String head,int digit,String foot,String fps,String audioInput,String videoCodec,String options[],String output){
	return makeJpegInputCommand(ffmpeg,inputDir,head,digit,foot,fps,audioInput,videoCodec,"pcm_s16le",options,output);
}


public static String[] makeCopyAudioCommand(String ffmpeg,String input,String output){
	List<String> list=new ArrayList<String>();
	list.add(ffmpeg);
	list.add("-i");
	list.add(input);
	
	list.add("-acodec");
	list.add("copy");
	
	list.add("-vn");
	
	list.add(output);
	
	return (String[])list.toArray(new String[0]);
}

public static String[] makeCopyVideoCommand(String ffmpeg,String input,String output){
	List<String> list=new ArrayList<String>();
	list.add(ffmpeg);
	list.add("-i");
	list.add(input);
	
	list.add("-vcodec");
	list.add("copy");
	
	list.add("-an");
	
	list.add(output);
	
	return (String[])list.toArray(new String[0]);
}
}
